package com.doge.walknovel.business.reader

import android.content.Context
import android.graphics.RectF
import android.util.AttributeSet
import android.view.GestureDetector
import android.view.MotionEvent
import androidx.constraintlayout.widget.ConstraintLayout
import com.doge.walknovel.api.observeOnMain
import com.doge.walknovel.api.subscribeOnIO
import com.doge.walknovel.utils.isMainThread
import com.doge.walknovel.utils.log
import com.doge.walknovel.utils.screenHeight
import com.doge.walknovel.utils.screenWidth
import io.reactivex.Observable
import io.reactivex.disposables.Disposable
import java.util.concurrent.TimeUnit

class NovelGestureLayout @JvmOverloads constructor(
    context: Context,
    attrs: AttributeSet? = null
) : ConstraintLayout(context, attrs) {
    interface Listener {
        fun onCenterClick()
    }

    private val center by lazy {
        RectF(screenWidth * 0.15f, screenHeight * 0.25f, screenWidth * 0.85f, screenHeight * 0.75f)
    }
    private val listeners = mutableListOf<Listener>()
    private var clickListener: OnClickListener? = null
    private var longClickListener: OnLongClickListener? = null
    fun addListener(listener: Listener) {
        if (!listeners.contains(listener)) {
            listeners.add(listener)
        }
    }

    override fun setOnClickListener(listener: OnClickListener?) {
        clickListener = listener
    }

    override fun setOnLongClickListener(listener: OnLongClickListener?) {
        longClickListener = listener
    }

    override fun dispatchTouchEvent(event: MotionEvent?): Boolean {
        handleDispatchTouchEvent(event)
        return super.dispatchTouchEvent(event)
    }

    private fun handleDispatchTouchEvent(event: MotionEvent?) {
        gestureDetector.onTouchEvent(event)
    }

    private val gestureDetector =
        GestureDetector(context, object : GestureDetector.SimpleOnGestureListener() {
            // forward long click listener
            override fun onLongPress(e: MotionEvent) {
                longClickListener?.onLongClick(this@NovelGestureLayout)
            }
        }).apply {
            setOnDoubleTapListener(object : GestureDetector.OnDoubleTapListener {
                override fun onSingleTapConfirmed(e: MotionEvent?): Boolean {
                    clickListener?.onClick(this@NovelGestureLayout)
                    if (!interceptTouchEvent && isCenterClicked(e)) {
                        listeners.toList().forEach { it.onCenterClick() }
                    }
                    return true
                }

                override fun onDoubleTapEvent(e: MotionEvent?) = false
                override fun onDoubleTap(e: MotionEvent?): Boolean = true
            })
        }

    private fun isCenterClicked(e: MotionEvent?): Boolean {
        if (e == null) return false
        log("${e.x} ${e.y} ${center.left} ${center.top} ${center.right} ${center.bottom}")
        return (e.x >= center.left && e.x <= center.right &&
                e.y >= center.top && e.y <= center.bottom)
    }

    companion object {
        private var idleTask: Disposable? = null
        private var interceptTouchEvent = false

        fun postInterceptTouchEvent() {
            require(isMainThread())
            interceptTouchEvent = true
            idleTask?.dispose()
            idleTask = Observable.timer(1, TimeUnit.SECONDS)
                .subscribeOnIO()
                .observeOnMain()
                .doOnNext { interceptTouchEvent = false }
                .subscribe()
        }
    }
}

